Summary

This workflow demonstrates the mitosRNAseq pipeline which identifies several types of small RNA from sequencing data from short reads of <50 nt. The following method collects sequence-based counts, sequence locations, genomic features, and annotations. The data we use is from killifish embyros anoxia experiments.

The step-by-step workflow we follow is illistrated below and a detailed method to perform small RNA seq on an academic HPC is decsribed in this document.

The following table shows the contents of the file samples.csv that contains metadata for our samples. We start with a total of 40 fastq files.

Sample Table

# Sample Condition Stage Input files
1 31_4d_t0 4d_t0 4 31_4d_t0.fastq.gz
2 32_4d_t0 4d_t0 4 32_4d_t0.fastq.gz
3 33_4d_t0 4d_t0 4 33_4d_t0.fastq.gz
4 34_4d_t0 4d_t0 4 34_4d_t0.fastq.gz
5 35_4d_4hrA 4d_4hrA 4 35_4d_4hrA.fastq.gz
6 36_4d_4hrA 4d_4hrA 4 36_4d_4hrA.fastq.gz
7 37_4d_4hrA 4d_4hrA 4 37_4d_4hrA.fastq.gz
8 38_4d_4hrA 4d_4hrA 4 38_4d_4hrA.fastq.gz
9 39_4d_24hrA 4d_24hrA 4 39_4d_24hrA.fastq.gz
10 40_4d_24hrA 4d_24hrA 4 40_4d_24hrA.fastq.gz
11 41_4d_24hrA 4d_24hrA 4 41_4d_24hrA.fastq.gz
12 42_4d_24hrA 4d_24hrA 4 42_4d_24hrA.fastq.gz
13 43_4d_2hrR 4d_2hrR 4 43_4d_2hrR.fastq.gz
14 44_4d_2hrR 4d_2hrR 4 44_4d_2hrR.fastq.gz
15 45_4d_2hrR 4d_2hrR 4 45_4d_2hrR.fastq.gz
16 46_4d_2hrR 4d_2hrR 4 46_4d_2hrR.fastq.gz
17 47_4d_24hrR 4d_24hrR 4 47_4d_24hrR.fastq.gz
18 48_4d_24hrR 4d_24hrR 4 48_4d_24hrR.fastq.gz
19 49_4d_24hrR 4d_24hrR 4 49_4d_24hrR.fastq.gz
20 50_4d_24hrR 4d_24hrR 4 50_4d_24hrR.fastq.gz
21 1_12d_t0 12d_t0 12 1_12d_t0.fastq.gz
22 2_12d_t0 12d_t0 12 2_12d_t0.fastq.gz
23 5_12d_t0 12d_t0 12 5_12d_t0.fastq.gz
24 6_12d_t0 12d_t0 12 6_12d_t0.fastq.gz
25 10_12d_4hrA 12d_4hrA 12 10_12d_4hrA.fastq.gz
26 11_12d_4hrA 12d_4hrA 12 11_12d_4hrA.fastq.gz
27 12_12d_4hrA 12d_4hrA 12 12_12d_4hrA.fastq.gz
28 7_12d_4hrA 12d_4hrA 12 7_12d_4hrA.fastq.gz
29 13_12d_24hrA 12d_24hrA 12 13_12d_24hrA.fastq.gz
30 16_12d_24hrA 12d_24hrA 12 16_12d_24hrA.fastq.gz
31 17_12d_24hrA 12d_24hrA 12 17_12d_24hrA.fastq.gz
32 18_12d_24hrA 12d_24hrA 12 18_12d_24hrA.fastq.gz
33 19_12d_2hrR 12d_2hrR 12 19_12d_2hrR.fastq.gz
34 21_12d_2hrR 12d_2hrR 12 21_12d_2hrR.fastq.gz
35 22_12d_2hrR 12d_2hrR 12 22_12d_2hrR.fastq.gz
36 23_12d_2hrR 12d_2hrR 12 23_12d_2hrR.fastq.gz
37 25_12d_24hrR 12d_24hrR 12 25_12d_24hrR.fastq.gz
38 28_12d_24hrR 12d_24hrR 12 28_12d_24hrR.fastq.gz
39 29_12d_24hrR 12d_24hrR 12 29_12d_24hrR.fastq.gz
40 30_12d_24hrR 12d_24hrR 12 30_12d_24hrR.fastq.gz

QC for raw reads

Quality Control (QC) is done by running fastQC on raw reads to evaluate how good (or bad) our data looks.

Install software for Quality Check

conda

Set up a virtual environment in conda that has all of the Quality Control (QC) tools. We are using Miniconda. For creating sharable environments, create .yaml files for each environment you’re making.

conda create -n condafastqc fastqc
conda activate condafastqc
conda install -n multiqc

tmux

For almost every long-ish process, we use tmux to run tasks in a detached terminal window that can keep running if we want to log out or if we accidently log out.

tmux new -s fastqc

Executing

Creating a new file called fastqcr.R that has the script to run fastqc through R. We use this script to automate the process for a list of files in a directory. Running commands through various scripts also keeps a record of our commands.

if (!require("fastqcr")) {
        install.packages("fastqcr", repos="http://cran.us.r-project.org")
        library(fastqcr)
} else {library(fastqcr)}
fastqc(fq.dir="/path/to/directory/init_fastq_files",
      qc.dir="/path/to/directory/fastqc/init_fastqc",
      threads=20)

Running the script with the following command:

Rscript fastqcr.R

Press Ctrl+B and then D for detaching this tmux window. You can log out from your remote computer (HPC) and close your terminal window now while this process keeps running on your remote computer. To get back to this window, log in to your remote computer, and use the command tmux a -t fastqc. F or more information, check tmux.

We will get a fastqc HTML file in the output fastqc directory for each fastq sequence in the input init_fastq_files directory.

FastQC Output

General Statistics from multiqc

Sample PercentDups PercentGC BPMedianReadLength MillionsSeqs
10_12d_4hrA 94.1 51 36 12.6
11_12d_4hrA 92.7 51 36 16.2
12_12d_4hrA 87.4 52 36 9.0
13_12d_24hrA 90.5 53 36 8.5
16_12d_24hrA 91.1 50 36 7.9
17_12d_24hrA 92.4 50 36 29.9
18_12d_24hrA 84.6 52 36 11.8
19_12d_2hrR 87.6 52 36 11.6
1_12d_t0 86.4 51 36 8.7
21_12d_2hrR 95.4 54 36 9.8
22_12d_2hrR 80.5 52 36 6.7
23_12d_2hrR 89.3 52 36 7.8
25_12d_24hrR 88.1 53 36 13.5
28_12d_24hrR 91.1 55 36 5.9
29_12d_24hrR 91.4 54 36 8.3
2_12d_t0 91.5 54 36 8.3
30_12d_24hrR 79.9 53 36 12.8
31_4d_t0 79.3 52 50 11.9
32_4d_t0 80.1 53 50 11.6
33_4d_t0 86.3 51 50 13.7
34_4d_t0 82.9 52 50 15.2
35_4d_4hrA 88.4 52 50 11.0
36_4d_4hrA 87.0 51 50 13.8
37_4d_4hrA 84.7 52 50 15.6
38_4d_4hrA 84.4 51 50 15.3
39_4d_24hrA 79.7 53 50 12.4
40_4d_24hrA 74.4 51 50 12.9
41_4d_24hrA 79.3 52 50 9.7
42_4d_24hrA 85.6 53 50 16.7
43_4d_2hrR 88.3 52 50 13.0
44_4d_2hrR 81.5 44 101 11.0
45_4d_2hrR 87.9 44 101 13.8
46_4d_2hrR 88.9 52 50 16.9
47_4d_24hrR 72.8 45 101 14.6
48_4d_24hrR 83.2 53 50 13.4
49_4d_24hrR 87.1 51 50 22.8
50_4d_24hrR 88.9 41 101 14.8
5_12d_t0 81.3 53 36 11.2
6_12d_t0 81.7 53 36 13.6
7_12d_4hrA 81.4 52 36 10.5

Sequence Counts for each sample

Sequence Counts

Sequence Counts

The mean quality scores per base in the read

Per Base Quality

Per Base Quality

The average quality scores per sequence

Per Sequence Quality

Per Sequence Quality

The GC content per sequence

GC conetent

GC conetent

Sequence Duplication

Duplication in each sequence

Duplication in each sequence

Overrepresented sequences

Total overrepresented sequences found in each sample

Total overrepresented sequences found in each sample

Adapter Content

Adapters found at sequence positions

Adapters found at sequence positions

Overall Pass/Fail

Checking if each sample passes or fails in various meteris

Checking if each sample passes or fails in various meteris

Sequence length distribution

All samples had sequences of a single length (50bp , 36bp , 101bp).

Trimming

Trimming is done with Trimmomatic in our case, however, other tools like cutadapt or fastp may also be used. This tool runs through the following bash script

FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/copied_old_infiles/init_fastq_files/*.fastq.gz"
for f in $FILES
    do
        b=`basename $f`
        echo Running trimming for the file $b

        c=${b::-9}
        o="$c.trim.fastq"
    log="$c.out.log"
        c="$c.log.txt"
        java -jar /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/trim/Trimmomatic-0.39/trimmomatic-0.39.jar SE -threads 20 -phred33 -trimlog $c $f $o ILLUMINACLIP:/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/copied_old_infiles/adapter_contamination_sequences_AR3.txt:2:30:5:1:true SLIDINGWINDOW:5:15 LEADING:20 TRAILING:20 MINLEN:15 2> $log
    done
Reads Surviving

Reads Surviving

Sample TotalReads SurvivingReads PercentSurviving DroppedReads PercentDropped
10_12d_4hrA 12625447 4421375 35.0 8204072 65.0
11_12d_4hrA 16238016 8893201 54.8 7344815 45.2
12_12d_4hrA 9024387 7219072 80.0 1805315 20.0
13_12d_24hrA 8467459 5182199 61.2 3285260 38.8
16_12d_24hrA 7908381 6458185 81.7 1450196 18.3
17_12d_24hrA 29872147 17868683 59.8 12003464 40.2
18_12d_24hrA 11793810 8182929 69.4 3610881 30.6
19_12d_2hrR 11606761 9574385 82.5 2032376 17.5
1_12d_t0 8698124 6498924 74.7 2199200 25.3
21_12d_2hrR 9784686 3585294 36.6 6199392 63.4
22_12d_2hrR 6741253 4728213 70.1 2013040 29.9
23_12d_2hrR 7836111 4455897 56.9 3380214 43.1
25_12d_24hrR 13534542 8957294 66.2 4577248 33.8
28_12d_24hrR 5866632 2402889 41.0 3463743 59.0
29_12d_24hrR 8305061 2923930 35.2 5381131 64.8
2_12d_t0 8344087 6946381 83.2 1397706 16.8
30_12d_24hrR 12811149 8785705 68.6 4025444 31.4
31_4d_t0 11936271 10306761 86.3 1629510 13.7
32_4d_t0 11595360 7974434 68.8 3620926 31.2
33_4d_t0 13655749 10422782 76.3 3232967 23.7
34_4d_t0 15201813 11186661 73.6 4015152 26.4
35_4d_4hrA 11045591 7821501 70.8 3224090 29.2
36_4d_4hrA 13840101 9383343 67.8 4456758 32.2
37_4d_4hrA 15579833 12373672 79.4 3206161 20.6
38_4d_4hrA 15286687 12142640 79.4 3144047 20.6
39_4d_24hrA 12442304 9755623 78.4 2686681 21.6
40_4d_24hrA 12866355 11130799 86.5 1735556 13.5
41_4d_24hrA 9720710 8032689 82.6 1688021 17.4
42_4d_24hrA 16698310 12979297 77.7 3719013 22.3
43_4d_2hrR 12989273 9158318 70.5 3830955 29.5
44_4d_2hrR 10968948 8421811 76.8 2547137 23.2
45_4d_2hrR 13812376 6527219 47.3 7285157 52.7
46_4d_2hrR 16946884 12011097 70.9 4935787 29.1
47_4d_24hrR 14627707 12933658 88.4 1694049 11.6
48_4d_24hrR 13383720 10269804 76.7 3113916 23.3
49_4d_24hrR 22803428 18172334 79.7 4631094 20.3
50_4d_24hrR 14759393 7495120 50.8 7264273 49.2
5_12d_t0 11217968 7594023 67.7 3623945 32.3
6_12d_t0 13607922 9592402 70.5 4015520 29.5
7_12d_4hrA 10489257 6515199 62.1 3974058 37.9

QC for trimmed reads

Quality Control (QC) is done for the trimmed reads with fastQC. We activate the conda environment condafastqc for this process.

if (!require("fastqcr")) {
        install.packages("fastqcr", repos="http://cran.us.r-project.org")
        library(fastqcr)
} else {library(fastqcr)}
fastqc(fq.dir="/path/to/directory/trimmed_fastq_files",
      qc.dir="/path/to/directory/fastqc/trim_fastqc",
      threads=20)

Running the script with the following command:

Rscript fastqcr.R

FastQC Output

Plots for each FASTQC metric after trimming is shown below. All the adapters were removed and overall quality looks better.

General Statistics from multiqc

Sample PercentDups PercentGC BPMedianReadLength MillionsSeqs
10_12d_4hrA 89.4 50 22 4.4
11_12d_4hrA 90.3 49 22 8.9
12_12d_4hrA 88.7 51 22 7.2
13_12d_24hrA 88.4 50 22 5.2
16_12d_24hrA 91.9 48 22 6.5
17_12d_24hrA 91.2 48 22 17.9
18_12d_24hrA 84.9 50 22 8.2
19_12d_2hrR 88.5 51 22 9.6
1_12d_t0 86.7 49 22 6.5
21_12d_2hrR 90.5 47 22 3.6
22_12d_2hrR 80.9 50 22 4.7
23_12d_2hrR 86.9 49 22 4.5
25_12d_24hrR 86.6 50 22 9.0
28_12d_24hrR 84.3 50 22 2.4
29_12d_24hrR 83.9 50 22 2.9
2_12d_t0 93.8 53 22 6.9
30_12d_24hrR 78.7 51 22 8.8
31_4d_t0 80.8 49 22 10.3
32_4d_t0 77.1 50 22 8.0
33_4d_t0 86.5 48 22 10.4
34_4d_t0 81.7 51 22 11.2
35_4d_4hrA 86.5 50 22 7.8
36_4d_4hrA 82.7 49 22 9.4
37_4d_4hrA 84.8 51 22 12.4
38_4d_4hrA 84.2 48 22 12.1
39_4d_24hrA 79.1 51 23 9.8
40_4d_24hrA 73.6 50 27 11.1
41_4d_24hrA 79.0 49 22 8.0
42_4d_24hrA 85.3 50 22 13.0
43_4d_2hrR 86.9 50 22 9.2
44_4d_2hrR 82.1 50 20 8.4
45_4d_2hrR 80.0 50 20 6.5
46_4d_2hrR 88.4 48 22 12.0
47_4d_24hrR 73.3 48 26 12.9
48_4d_24hrR 82.6 52 22 10.3
49_4d_24hrR 87.9 49 22 18.2
50_4d_24hrR 84.4 49 20 7.5
5_12d_t0 81.2 50 22 7.6
6_12d_t0 82.7 51 22 9.6
7_12d_4hrA 79.5 50 22 6.5

Sequence Counts for each sample

Sequence Counts

Sequence Counts

The mean quality scores per base in the read

Per Base Quality

Per Base Quality

The average quality scores per sequence

Per Sequence Quality

Per Sequence Quality

The GC content per sequence

GC conetent

GC conetent

Sequence Duplication

Duplication in each sequence

Duplication in each sequence

Overrepresented sequences

Total overrepresented sequences found in each sample

Total overrepresented sequences found in each sample

Overall Pass/Fail

Checking if each sample passes or fails in various meteris

Checking if each sample passes or fails in various meteris

Sequence length distribution

length distribution of sequences

length distribution of sequences

Alignment

First things first- create a conda environment that has bowtie, samtools, picard, and bedtools.

conda create -n condabowtie bowtie samtools picard bedtools

The trimmed reads are aligned to the reference genome using bowtie. To analyze reads mapping with mitochondrial genome, we perform the alignment in two steps.

  1. Complete Genome (with mitochondrial genome)- with algenome.fa
  2. Only the Mitochondrial genome which is extracted from genome.fa- almitogenome.fa

To begin alignment, we make bowtie indexes, this is done in two sets.

bowtie-index algenome.fa
bowtie-index almitogenome.fa

Alignment with genome

The alignment was done on the trimmed reads from previous section.

#!/bin/bash
FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/trim/*.fastq"
for f in $FILES
    do
        b=`basename $f`
        echo Running trimming for the file $b
        t=${b::-6}
        o="$t.sam"
        uo="$t.mapped.fq"
        echo Output file is $o
        bowtie \
     -p 20 \
         -t \
     -k 5 \
     --best \
     --strata \
     -e 99999 \
     -v 0 \
     -l 15 \
     --chunkmbs 2048 \
     -x /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/bowtie_index_alim/algenome \
     -q $f \
     --al $uo \
     --sam --no-unal > $o 2> $t.bowtie.log
    done
#done

The following stats show alignment QC.

Bowtie Alignment Stats with Genome

Bowtie Alignment Stats with Genome

This table shows the number of reads aligned in each sample (MillionAlignedReads). It also shows the number of aligments of various reads that includes multimapped reads (MillionMappedReads).

Sample PercentAligned MillionAlignedReads MillionMappedReads
10_12d_4hrA 73.2 3.2 8.0
11_12d_4hrA 73.6 6.5 15.4
12_12d_4hrA 70.4 5.1 12.4
13_12d_24hrA 69.6 3.6 8.7
16_12d_24hrA 77.5 5.0 10.3
17_12d_24hrA 75.8 13.5 31.4
18_12d_24hrA 73.7 6.0 15.0
19_12d_2hrR 71.9 6.9 16.8
1_12d_t0 73.3 4.8 11.1
21_12d_2hrR 77.8 2.8 5.3
22_12d_2hrR 66.2 3.1 7.4
23_12d_2hrR 73.2 3.3 7.8
25_12d_24hrR 69.7 6.2 15.0
28_12d_24hrR 65.3 1.6 3.7
29_12d_24hrR 70.9 2.1 5.0
2_12d_t0 76.9 5.3 13.1
30_12d_24hrR 65.5 5.8 13.8
31_4d_t0 62.0 6.4 11.8
32_4d_t0 73.5 5.9 12.2
33_4d_t0 80.6 8.4 15.0
34_4d_t0 70.5 7.9 15.8
35_4d_4hrA 71.5 5.6 9.2
36_4d_4hrA 62.1 5.8 8.3
37_4d_4hrA 69.1 8.6 16.4
38_4d_4hrA 76.1 9.2 15.4
39_4d_24hrA 79.0 7.7 17.2
40_4d_24hrA 52.3 5.8 10.9
41_4d_24hrA 63.0 5.1 8.8
42_4d_24hrA 66.6 8.6 15.2
43_4d_2hrR 71.2 6.5 11.7
44_4d_2hrR 64.6 5.4 11.8
45_4d_2hrR 65.7 4.3 9.5
46_4d_2hrR 71.2 8.6 13.8
47_4d_24hrR 80.1 10.4 24.4
48_4d_24hrR 51.8 5.3 10.7
49_4d_24hrR 72.3 13.1 23.2
50_4d_24hrR 79.4 6.0 13.4
5_12d_t0 66.2 5.0 11.9
6_12d_t0 67.5 6.5 15.5
7_12d_4hrA 65.6 4.3 10.1

Alignment with mitochondria

The alignment was done on the trimmed reads from previous section.

The following stats show alignment QC.

#!/bin/bash
FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/trim/*.fastq"   
for f in $FILES
    do
        b=`basename $f`
        echo Running alignment for the file $b
        t=${b::-6}
        o="$t.sam"
    uo="$t.mapped.fq"
        echo Output file is $o
        bowtie \
     -p 20 \
         -t \
     -k 10 \
     --best \
     --strata \
     -e 99999 \
     -v 0 \
     -l 15 \
     --chunkmbs 2048 \
     -x /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/bowtie_mito_index/almitogenome \
     -q $f \
     --al $uo \
     --sam --no-unal > $o 2> $t.bowtie.log
    done
#done
Bowtie Alignment Stats with Mitochondrial Genome

Bowtie Alignment Stats with Mitochondrial Genome

This table shows the number of reads aligned in each sample (MillionAlignedReads). It also shows the number of aligments of various reads that includes multimapped reads (MillionMappedReads).

Sample PercentAligned MillionAlignedReads MillionMappedReads
10_12d_4hrA 0.34 0.01 0.02
11_12d_4hrA 0.47 0.04 0.04
12_12d_4hrA 0.41 0.03 0.03
13_12d_24hrA 0.50 0.03 0.03
16_12d_24hrA 0.52 0.03 0.03
17_12d_24hrA 3.25 0.58 0.59
18_12d_24hrA 6.22 0.51 0.52
19_12d_2hrR 0.92 0.09 0.09
1_12d_t0 1.25 0.08 0.08
21_12d_2hrR 0.79 0.03 0.03
22_12d_2hrR 4.43 0.21 0.21
23_12d_2hrR 2.68 0.12 0.12
25_12d_24hrR 4.72 0.42 0.43
28_12d_24hrR 0.32 0.01 0.01
29_12d_24hrR 4.08 0.12 0.12
2_12d_t0 0.25 0.02 0.02
30_12d_24hrR 8.18 0.72 0.73
31_4d_t0 4.99 0.51 0.52
32_4d_t0 10.12 0.81 0.82
33_4d_t0 1.99 0.21 0.21
34_4d_t0 6.72 0.75 0.77
35_4d_4hrA 0.43 0.03 0.03
36_4d_4hrA 0.59 0.06 0.06
37_4d_4hrA 1.10 0.14 0.14
38_4d_4hrA 5.67 0.69 0.70
39_4d_24hrA 8.32 0.81 0.83
40_4d_24hrA 7.77 0.87 0.88
41_4d_24hrA 7.50 0.60 0.61
42_4d_24hrA 2.13 0.28 0.28
43_4d_2hrR 0.61 0.06 0.06
44_4d_2hrR 1.00 0.08 0.09
45_4d_2hrR 4.69 0.31 0.31
46_4d_2hrR 1.07 0.13 0.13
47_4d_24hrR 16.68 2.16 2.19
48_4d_24hrR 0.18 0.02 0.02
49_4d_24hrR 1.49 0.27 0.28
50_4d_24hrR 2.22 0.17 0.17
5_12d_t0 6.11 0.46 0.47
6_12d_t0 6.47 0.62 0.63
7_12d_4hrA 5.39 0.35 0.36

Another QC that we could fo with the aligned read is with Picard. The following is the command line to do that:

FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alim_for_anno/alim_mito_anno/*sorted.bam"
for f in $FILES
    do
        b=`basename $f`
        echo Converting file $b
        o="$b.picard.txt"
        echo Output file is $o
    picard -Xmx5g CollectAlignmentSummaryMetrics I=$f O=$o R=/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/copied_old_infiles/GCF_001266775.1_Austrofundulus_limnaeus-1.0_genomic_andMITO.fna
    done
#done

Before we proceed, we need to sort the sam, convert it into bam and create a bam index (bai). This step ensures that we could store the alignments in acceptable binary format that takes less storage space and is compatible with subsequent steps.

FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alim_for_anno/alim_mito_anno/*.sam"
for f in $FILES
    do
        b=`basename $f`
        echo Converting $b to bam
        o=${b::-4}
        bam="$o.bam"
    sortedbam="$b.sorted.bam"
    
    echo Tmp file is $bam
        samtools view -b $f > $bam
    
        echo Output files are $sortedbam and its index
    samtools sort $bam -o $sortedbam
    samtools index $sortedbam
    echo Deleting Tmp file $bam 
    rm $bam 
    done
#done

Using aligned reads

We will create three files:

  1. Summary information that has read ID, sequence, reference location, and number of alignments.
  2. Exact location, genomic features of the reference location that the reads mapped to via bedtools.
  3. Counting the readcounts from bam files.
FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alim_for_anno/alim_mito_anno/*.bam"
for f in $FILES
    do
        b=`basename $f`
        echo $b
        o=${b::-4}
        o="$o.summary.txt"
    input_file="$f"
    output_file="$o.summary.txt"

    # Process the input file with samtools and awk
    samtools view $f | awk '{print $1, $10, $3, $4, $15}' | sort | uniq > "$output_file"
    echo "Output file written $output_file"
    done

The result is the following data for each file. The sample 1_12d_t0 is shown.

FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alim_for_anno/alim_mito_anno/*.bam"
for f in $FILES
    do
        b=`basename $f`
        echo $b
        o=${b::-4}
        bed="$o.bed"
    out="$o.bedtools.txt"
    gff="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/mito_genome/GCF_001266775.1_Austrofundulus_limnaeus_MITOonly.gff"
    bedtools intersect -a $f -b $gff -wo -f 1 -bed > $bed
    awk '!seen[$4]++' $bed > tmp.csv
    rm $bed
    awk '{print $4, $21}' tmp.csv > $out
    rm tmp.csv
    echo "Output file written $out"
    done

The result of above command gives us the following data for each file. The sample 1_12d_t0 is shown.

FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alim_for_anno/alim_mito_anno/*.bam"
for f in $FILES
    do
        b=`basename $f`
        echo $b
        o=${b::-4}
        o="$o.readcount.txt"
        echo Output file is $o
    # Count unique occurrences of column 10
    samtools view $f | awk '{print $10}'| sort | uniq -c > "$o"
    echo "Output written to $o"
    done

The result of above command gives us the following data for each file. The sample 1_12d_t0 is shown.

miRTrace

Running mirtrace with the following command.

mirtrace qc --species dre --config seq_address.txt

Looking at the results:

sports

Executing sports tool on mapped reads only. We use the following command to run:

#!/bin/bash
sports.pl -i seqs_alim_mito.txt \
-o /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alimnaeus/gen_input_fastq/SPORTS/out_sports/REDO/mito_mapped_reads \
-k \
-M 2 \
-p 20 \
-g /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/bowtie_mito_index/almitogenome \
-m /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alimnaeus/gen_input_fastq/SPORTS/sports1.1/db/Danio_rerio/miRBase_21/miRBase_21-dre \
-r /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alimnaeus/gen_input_fastq/SPORTS/sports1.1/db/Danio_rerio/rRNA_db/zebrafish_rRNA \
-t /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alimnaeus/gen_input_fastq/SPORTS/sports1.1/db/Danio_rerio/GtRNAdb/danRer6-tRNAs \
-w /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alimnaeus/gen_input_fastq/SPORTS/sports1.1/db/Danio_rerio/piRBase/piR_dre_v1.0 \
-e /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alimnaeus/gen_input_fastq/SPORTS/sports1.1/db/Danio_rerio/Ensembl/Danio_rerio.GRCz10.ncrna \
-f /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alimnaeus/gen_input_fastq/SPORTS/sports1.1/db/Danio_rerio/Rfam_12.3/Rfam-12.3-zebrafish

This will generate a number of output files, from which the tables generated as a result file *_output.txt for each sample are taken and are used to extract annotation of mapped reads. Top 50 rows of this table are shown for the sample 10_12d_4hrA below.

It also generates a number of plots to categorize the annotations and their length distributions for each sample.

Compiling output files

At the end, we need to compile all the output files into a single dataframe that can be exported to further do downstream processing such as statistics, differential expression, and clustering.

We provide an R script that compiles these output files:

  1. Annotation: From sports- *.mapped_output.txt
  2. Alignment summary: From .bam files with samtools- *.summary.txt
  3. Readcount: From .bam files with samtools and awk- *.readcount.txt
  4. Location: From .bam files with bedtools- *.bedtools.txt

In addition, we also need a sample design file (.csv format) that has details about the samples. This file makes it easier to do statistical analysis on the data using R packages like DESeq2, ExpressionSet, and EdgeR.

You would alter the following lines in the R script that basically tells the program where these txt files are located.

parent_dir <- "D:/PSU_work/smrnaseq/mito_map"
samples <- "D:/PSU_work/smrnaseq/mito_map/design_samples.csv"
readcount_txt_pattern <- "sorted.readcount.txt$"
output_txt_pattern <- "mapped_output.txt$"
summary_txt_pattern <- "summary.txt$"
bedtools_txt_pattern <- "bedtools.txt$"

Set pattern of filenames: these files are searched in the parent_dir recursively. Make sure that the parent_dir contains these files and the pattern should be unique to list the files that we need.

Visualizing

We use the alignments with mitochondrial genome to view the aligned reads.

Jbrowse is used to explore alignments.

Files used:

  1. Aligned bam files for each sample and its corresponding index file (bam, bai)
  2. Reference genome for mitochondria (.fasta) and its index file (.fai)
  3. Genome feature file (.gff) for mitochondrial genome

Click to enlarge

This figure shows mitochondiral genome of 100bp length from 17100 to 17199. On this genome, we see 1) the colored basepairs, 2) Genomic features of the mentioned length, 3) Alignments from 4 samples (4d t0 replicates) that show reads aligned to the genome colored by strand while also showing the coverage histogram in grey.

LS0tCnRpdGxlOiAibWl0b3NSTkFzZXEgV29ya2Zsb3ciCmRhdGU6IDA4LTE1LTIwMjQKb3V0cHV0OiAKICAgIGh0bWxfbm90ZWJvb2s6CiAgICAgICAgdG9jOiBUUlVFCiAgICAgICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKCiMjICBTdW1tYXJ5ClRoaXMgd29ya2Zsb3cgZGVtb25zdHJhdGVzIHRoZSBtaXRvc1JOQXNlcSBwaXBlbGluZSB3aGljaCBpZGVudGlmaWVzIHNldmVyYWwgdHlwZXMgb2YKc21hbGwgUk5BIGZyb20gc2VxdWVuY2luZyBkYXRhIGZyb20gc2hvcnQgcmVhZHMgb2YgPDUwIG50LiBUaGUgZm9sbG93aW5nIG1ldGhvZCBjb2xsZWN0cyBzZXF1ZW5jZS1iYXNlZCAKY291bnRzLCBzZXF1ZW5jZSBsb2NhdGlvbnMsIGdlbm9taWMgZmVhdHVyZXMsIGFuZCBhbm5vdGF0aW9ucy4gClRoZSBkYXRhIHdlIHVzZSBpcyBmcm9tIGtpbGxpZmlzaCBlbWJ5cm9zIGFub3hpYSBleHBlcmltZW50cy4gCgpUaGUgc3RlcC1ieS1zdGVwIHdvcmtmbG93IHdlIGZvbGxvdyBpcyBpbGxpc3RyYXRlZCBiZWxvdyBhbmQgYSAKZGV0YWlsZWQgbWV0aG9kIHRvIHBlcmZvcm0gc21hbGwgUk5BIHNlcSBvbiBhbiBhY2FkZW1pYyBIUEMgaXMgZGVjc3JpYmVkIGluIHRoaXMgZG9jdW1lbnQuIAoKIVtdKC9ob21lL2dhemFsL0RvY3VtZW50cy9QU1Vfd29yay9zUk5BX2dhemFsL2RvY3VtZW50YXRpb24vRmlndXJlIDEucG5nKQoKVGhlIGZvbGxvd2luZyB0YWJsZSBzaG93cyB0aGUgY29udGVudHMgb2YgdGhlIGZpbGUgKipzYW1wbGVzLmNzdioqIHRoYXQgY29udGFpbnMgbWV0YWRhdGEgZm9yIG91ciBzYW1wbGVzLgpXZSBzdGFydCB3aXRoIGEgdG90YWwgb2YgNDAgZmFzdHEgZmlsZXMuCgojIyMgU2FtcGxlIFRhYmxlCmBgYHtyIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGZvcm1hdHRhYmxlKQpsaWJyYXJ5KHJlYWRyKQpkZl9zYW1wbGVzIDwtIHJlYWRfY3N2KCJzYW1wbGVzLmNzdiIsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpCmZvcm1hdHRhYmxlKGRmX3NhbXBsZXMsCiAgICAgICAgdGFibGUuYXR0ciA9ICdzdHlsZSA9ICJ3aWR0aDo1MCU7IGZvbnQtc2l6ZTo5MCU7IicKICAgICAgICApCmBgYAoKIyMgUUMgZm9yIHJhdyByZWFkcwoKUXVhbGl0eSBDb250cm9sIChRQykgaXMgZG9uZSBieSBydW5uaW5nIGZhc3RRQyBvbiByYXcgcmVhZHMgdG8gZXZhbHVhdGUgaG93IGdvb2QgKG9yIGJhZCkgb3VyIGRhdGEgbG9va3MuCgojIyMgSW5zdGFsbCBzb2Z0d2FyZSBmb3IgUXVhbGl0eSBDaGVjawoKKipjb25kYSoqCgpTZXQgdXAgYSB2aXJ0dWFsIGVudmlyb25tZW50IGluIGNvbmRhIHRoYXQgaGFzIGFsbCBvZiB0aGUgUXVhbGl0eSBDb250cm9sIChRQykgdG9vbHMuIApXZSBhcmUgdXNpbmcgW01pbmljb25kYV0oaHR0cHM6Ly9kb2NzLmFuYWNvbmRhLmNvbS9taW5pY29uZGEvKS4gCkZvciBjcmVhdGluZyBzaGFyYWJsZSBlbnZpcm9ubWVudHMsIGNyZWF0ZSAueWFtbCBmaWxlcyBmb3IgZWFjaCBlbnZpcm9ubWVudCB5b3UncmUgbWFraW5nLgoKYGBgCmNvbmRhIGNyZWF0ZSAtbiBjb25kYWZhc3RxYyBmYXN0cWMKY29uZGEgYWN0aXZhdGUgY29uZGFmYXN0cWMKY29uZGEgaW5zdGFsbCAtbiBtdWx0aXFjCmBgYAoKKip0bXV4KioKCkZvciBhbG1vc3QgZXZlcnkgbG9uZy1pc2ggcHJvY2VzcywgCndlIHVzZSB0bXV4IHRvIHJ1biB0YXNrcyBpbiBhIGRldGFjaGVkIHRlcm1pbmFsIHdpbmRvdyB0aGF0IGNhbiBrZWVwIHJ1bm5pbmcgaWYgd2Ugd2FudCB0byBsb2cgb3V0IG9yIGlmIHdlIGFjY2lkZW50bHkgbG9nIG91dC4KYGBgCnRtdXggbmV3IC1zIGZhc3RxYwpgYGAKCiMjIyBFeGVjdXRpbmcKCkNyZWF0aW5nIGEgbmV3IGZpbGUgY2FsbGVkICoqZmFzdHFjci5SKiogdGhhdCBoYXMgdGhlIHNjcmlwdCB0byBydW4gZmFzdHFjIHRocm91Z2ggUi4KV2UgdXNlIHRoaXMgc2NyaXB0IHRvIGF1dG9tYXRlIHRoZSBwcm9jZXNzIGZvciBhIGxpc3Qgb2YgZmlsZXMgaW4gYSBkaXJlY3RvcnkuIApSdW5uaW5nIGNvbW1hbmRzIHRocm91Z2ggdmFyaW91cyBzY3JpcHRzIGFsc28ga2VlcHMgYSByZWNvcmQgb2Ygb3VyIGNvbW1hbmRzLgoKYGBgCmlmICghcmVxdWlyZSgiZmFzdHFjciIpKSB7CiAgICAgICAgaW5zdGFsbC5wYWNrYWdlcygiZmFzdHFjciIsIHJlcG9zPSJodHRwOi8vY3Jhbi51cy5yLXByb2plY3Qub3JnIikKICAgICAgICBsaWJyYXJ5KGZhc3RxY3IpCn0gZWxzZSB7bGlicmFyeShmYXN0cWNyKX0KZmFzdHFjKGZxLmRpcj0iL3BhdGgvdG8vZGlyZWN0b3J5L2luaXRfZmFzdHFfZmlsZXMiLAogICAgICBxYy5kaXI9Ii9wYXRoL3RvL2RpcmVjdG9yeS9mYXN0cWMvaW5pdF9mYXN0cWMiLAogICAgICB0aHJlYWRzPTIwKQpgYGAKClJ1bm5pbmcgdGhlIHNjcmlwdCB3aXRoIHRoZSBmb2xsb3dpbmcgY29tbWFuZDoKYGBgClJzY3JpcHQgZmFzdHFjci5SCmBgYApQcmVzcyBgQ3RybCtCYCBhbmQgdGhlbiBgRGAgZm9yIGRldGFjaGluZyB0aGlzIHRtdXggd2luZG93LiAKWW91IGNhbiBsb2cgb3V0IGZyb20geW91ciByZW1vdGUgY29tcHV0ZXIgKEhQQykgYW5kIGNsb3NlIHlvdXIgdGVybWluYWwgCndpbmRvdyBub3cgd2hpbGUgdGhpcyBwcm9jZXNzIGtlZXBzIHJ1bm5pbmcgb24geW91ciByZW1vdGUgY29tcHV0ZXIuIApUbyBnZXQgYmFjayB0byB0aGlzIHdpbmRvdywgbG9nIGluIHRvIHlvdXIgcmVtb3RlIGNvbXB1dGVyLCBhbmQKIHVzZSB0aGUgY29tbWFuZCBgdG11eCBhIC10IGZhc3RxY2AuIEYKb3IgbW9yZSBpbmZvcm1hdGlvbiwgY2hlY2sgW3RtdXhdKGh0dHBzOi8vZ2l0aHViLmNvbS90bXV4L3RtdXgvd2lraS9HZXR0aW5nLVN0YXJ0ZWQpLiAKCldlIHdpbGwgZ2V0IGEgZmFzdHFjIEhUTUwgZmlsZSBpbiB0aGUgb3V0cHV0IGZhc3RxYyBkaXJlY3RvcnkgZm9yIAplYWNoIGZhc3RxIHNlcXVlbmNlIGluIHRoZSBpbnB1dCBpbml0X2Zhc3RxX2ZpbGVzIGRpcmVjdG9yeS4KCiMjIyBGYXN0UUMgT3V0cHV0CgoqKkdlbmVyYWwgU3RhdGlzdGljcyBmcm9tIG11bHRpcWMqKgpgYGB7ciBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJywgd2FybmluZz1GQUxTRX0KbGlicmFyeShyZWFkcikKbGlicmFyeShmb3JtYXR0YWJsZSkKZGZfc3RhdHMgPC0gcmVhZF90c3YoIm11bHRpcWNfaW5pdF9mYXN0cS9nZW5lcmFsX3N0YXRzX3RhYmxlLnRzdiIsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpCmlzLm51bSA8LSBzYXBwbHkoZGZfc3RhdHMsIGlzLm51bWVyaWMpCmRmX3N0YXRzW2lzLm51bV0gPC0gbGFwcGx5KGRmX3N0YXRzW2lzLm51bV0sIHJvdW5kLCAxKQpmb3JtYXR0YWJsZShkZl9zdGF0cywgbGlzdCgKICAgICdQZXJjZW50RHVwcycgPSBjb2xvcl9iYXIoIiNFOTk2N0EiKSwKICAgICdQZXJjZW50R0MnID0gY29sb3JfYmFyKCIjREFBNTIwIiksCiAgICAnQlBNZWRpYW5SZWFkTGVuZ3RoJyA9IGNvbG9yX2JhcigiIzY2Q0RBQSIpLAogICAgJ01pbGxpb25zU2VxcycgPSBjb2xvcl9iYXIoIiNEQTcwRDYiKSksCiAgICB0YWJsZS5hdHRyID0gImNsYXNzPVwndGFibGUgdGFibGUtY29uZGVuc2VkXCcsIHN0eWxlPVwnd2lkdGg6ODAlOyBmb250LXNpemU6OTAlO1wnIgopCmBgYAoKKipTZXF1ZW5jZSBDb3VudHMgZm9yIGVhY2ggc2FtcGxlKioKCiFbU2VxdWVuY2UgQ291bnRzXShtdWx0aXFjX2luaXRfZmFzdHEvbXVsdGlxY19wbG90cy9mYXN0cWNfc2VxdWVuY2VfY291bnRzX3Bsb3QucG5nKXt3aWR0aD01NTBweH0KCioqVGhlIG1lYW4gcXVhbGl0eSBzY29yZXMgcGVyIGJhc2UgaW4gdGhlIHJlYWQqKgoKIVtQZXIgQmFzZSBRdWFsaXR5XShtdWx0aXFjX2luaXRfZmFzdHEvbXVsdGlxY19wbG90cy9mYXN0cWNfcGVyX2Jhc2Vfc2VxdWVuY2VfcXVhbGl0eV9wbG90LnBuZyl7d2lkdGg9NTUwcHh9CgoqKlRoZSBhdmVyYWdlIHF1YWxpdHkgc2NvcmVzIHBlciBzZXF1ZW5jZSoqCgohW1BlciBTZXF1ZW5jZSBRdWFsaXR5XShtdWx0aXFjX2luaXRfZmFzdHEvbXVsdGlxY19wbG90cy9mYXN0cWNfcGVyX3NlcXVlbmNlX3F1YWxpdHlfc2NvcmVzX3Bsb3QucG5nKXt3aWR0aD01NTBweH0KCioqVGhlIEdDIGNvbnRlbnQgcGVyIHNlcXVlbmNlKioKCiFbR0MgY29uZXRlbnRdKG11bHRpcWNfaW5pdF9mYXN0cS9tdWx0aXFjX3Bsb3RzL2Zhc3RxY19wZXJfc2VxdWVuY2VfZ2NfY29udGVudF9wbG90LnBuZyl7d2lkdGg9NTUwcHh9CgoKKipTZXF1ZW5jZSBEdXBsaWNhdGlvbioqCgohW0R1cGxpY2F0aW9uIGluIGVhY2ggc2VxdWVuY2VdKG11bHRpcWNfaW5pdF9mYXN0cS9tdWx0aXFjX3Bsb3RzL2Zhc3RxY19zZXF1ZW5jZV9kdXBsaWNhdGlvbl9sZXZlbHNfcGxvdC5wbmcpe3dpZHRoPTU1MHB4fQoKKipPdmVycmVwcmVzZW50ZWQgc2VxdWVuY2VzKioKCiFbVG90YWwgb3ZlcnJlcHJlc2VudGVkIHNlcXVlbmNlcyBmb3VuZCBpbiBlYWNoIHNhbXBsZV0obXVsdGlxY19pbml0X2Zhc3RxL211bHRpcWNfcGxvdHMvZmFzdHFjX292ZXJyZXByZXNlbnRlZF9zZXF1ZW5jZXNfcGxvdC5wbmcpe3dpZHRoPTU1MHB4fQoKKipBZGFwdGVyIENvbnRlbnQqKgoKIVtBZGFwdGVycyBmb3VuZCBhdCBzZXF1ZW5jZSBwb3NpdGlvbnNdKG11bHRpcWNfaW5pdF9mYXN0cS9tdWx0aXFjX3Bsb3RzL2Zhc3RxY19hZGFwdGVyX2NvbnRlbnRfcGxvdC5wbmcpe3dpZHRoPTU1MHB4fQoKKipPdmVyYWxsIFBhc3MvRmFpbCoqCgohW0NoZWNraW5nIGlmIGVhY2ggc2FtcGxlIHBhc3NlcyBvciBmYWlscyBpbiB2YXJpb3VzIG1ldGVyaXNdKG11bHRpcWNfaW5pdF9mYXN0cS9tdWx0aXFjX3Bsb3RzL2Zhc3RxYy1zdGF0dXMtY2hlY2staGVhdG1hcC5wbmcpe3dpZHRoPTU1MHB4fQoKKipTZXF1ZW5jZSBsZW5ndGggZGlzdHJpYnV0aW9uKioKCkFsbCBzYW1wbGVzIGhhZCBzZXF1ZW5jZXMgb2YgYSBzaW5nbGUgbGVuZ3RoICg1MGJwICwgMzZicCAsIDEwMWJwKS4KCiMjIFRyaW1taW5nCgpUcmltbWluZyBpcyBkb25lIHdpdGggVHJpbW1vbWF0aWMgaW4gb3VyIGNhc2UsIGhvd2V2ZXIsIG90aGVyIHRvb2xzIGxpa2UgY3V0YWRhcHQgb3IgZmFzdHAgbWF5IGFsc28gYmUgdXNlZC4KVGhpcyB0b29sIHJ1bnMgdGhyb3VnaCB0aGUgZm9sbG93aW5nIGJhc2ggc2NyaXB0CgpgYGAKRklMRVM9Ii9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL2NvcGllZF9vbGRfaW5maWxlcy9pbml0X2Zhc3RxX2ZpbGVzLyouZmFzdHEuZ3oiCmZvciBmIGluICRGSUxFUwogICAgZG8KICAgICAgICBiPWBiYXNlbmFtZSAkZmAKICAgICAgICBlY2hvIFJ1bm5pbmcgdHJpbW1pbmcgZm9yIHRoZSBmaWxlICRiCgogICAgICAgIGM9JHtiOjotOX0KICAgICAgICBvPSIkYy50cmltLmZhc3RxIgoJbG9nPSIkYy5vdXQubG9nIgogICAgICAgIGM9IiRjLmxvZy50eHQiCiAgICAgICAgamF2YSAtamFyIC9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL3RyaW0vVHJpbW1vbWF0aWMtMC4zOS90cmltbW9tYXRpYy0wLjM5LmphciBTRSAtdGhyZWFkcyAyMCAtcGhyZWQzMyAtdHJpbWxvZyAkYyAkZiAkbyBJTExVTUlOQUNMSVA6L2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvY29waWVkX29sZF9pbmZpbGVzL2FkYXB0ZXJfY29udGFtaW5hdGlvbl9zZXF1ZW5jZXNfQVIzLnR4dDoyOjMwOjU6MTp0cnVlIFNMSURJTkdXSU5ET1c6NToxNSBMRUFESU5HOjIwIFRSQUlMSU5HOjIwIE1JTkxFTjoxNSAyPiAkbG9nCiAgICBkb25lCmBgYAoKIVtSZWFkcyBTdXJ2aXZpbmddKHRyaW1tb21hdGljL3RyaW1tb21hdGljX3Bsb3QucG5nKXt3aWR0aD01NTBweH0KCmBgYHtyIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGZvcm1hdHRhYmxlKQpkZl9zdGF0cyA8LSByZWFkX3RzdigidHJpbW1vbWF0aWMvdHJpbW1vbWF0aWNfcGxvdC50c3YiLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKQppcy5udW0gPC0gc2FwcGx5KGRmX3N0YXRzLCBpcy5udW1lcmljKQpkZl9zdGF0c1tpcy5udW1dIDwtIGxhcHBseShkZl9zdGF0c1tpcy5udW1dLCByb3VuZCwgMSkKZm9ybWF0dGFibGUoZGZfc3RhdHMsIGxpc3QoCiAgICAnVG90YWxSZWFkcycgPSBjb2xvcl9iYXIoIiNCREI3NkIiKSwKICAgICdTdXJ2aXZpbmdSZWFkcycgPSBjb2xvcl9iYXIoIiM5MEVFOTAiKSwKICAgICdQZXJjZW50U3Vydml2aW5nJyA9IGNvbG9yX2JhcigiIzMyQ0QzMiIpLAogICAgJ0Ryb3BwZWRSZWFkcycgPSBjb2xvcl9iYXIoIiNGMDgwODAiKSwKICAgICdQZXJjZW50RHJvcHBlZCcgPSBjb2xvcl9iYXIoIiNDRDVDNUMiKSksCiAgICB0YWJsZS5hdHRyID0gImNsYXNzPVwndGFibGUgdGFibGUtY29uZGVuc2VkXCcsIHN0eWxlPVwnd2lkdGg6MTAwJTsgZm9udC1zaXplOjkwJTtcJyIKKQpgYGAKCQkJCQoKIyMgUUMgZm9yIHRyaW1tZWQgcmVhZHMKClF1YWxpdHkgQ29udHJvbCAoUUMpIGlzIGRvbmUgZm9yIHRoZSB0cmltbWVkIHJlYWRzIHdpdGggZmFzdFFDLiAKV2UgYWN0aXZhdGUgdGhlIGNvbmRhIGVudmlyb25tZW50IGBjb25kYWZhc3RxY2AgZm9yIHRoaXMgcHJvY2Vzcy4KCmBgYAppZiAoIXJlcXVpcmUoImZhc3RxY3IiKSkgewogICAgICAgIGluc3RhbGwucGFja2FnZXMoImZhc3RxY3IiLCByZXBvcz0iaHR0cDovL2NyYW4udXMuci1wcm9qZWN0Lm9yZyIpCiAgICAgICAgbGlicmFyeShmYXN0cWNyKQp9IGVsc2Uge2xpYnJhcnkoZmFzdHFjcil9CmZhc3RxYyhmcS5kaXI9Ii9wYXRoL3RvL2RpcmVjdG9yeS90cmltbWVkX2Zhc3RxX2ZpbGVzIiwKICAgICAgcWMuZGlyPSIvcGF0aC90by9kaXJlY3RvcnkvZmFzdHFjL3RyaW1fZmFzdHFjIiwKICAgICAgdGhyZWFkcz0yMCkKYGBgCgpSdW5uaW5nIHRoZSBzY3JpcHQgd2l0aCB0aGUgZm9sbG93aW5nIGNvbW1hbmQ6CmBgYApSc2NyaXB0IGZhc3RxY3IuUgpgYGAKCiMjIyBGYXN0UUMgT3V0cHV0CgpQbG90cyBmb3IgZWFjaCBGQVNUUUMgbWV0cmljIGFmdGVyIHRyaW1taW5nIGlzIHNob3duIGJlbG93LiAKQWxsIHRoZSBhZGFwdGVycyB3ZXJlIHJlbW92ZWQgYW5kIG92ZXJhbGwgcXVhbGl0eSBsb29rcyBiZXR0ZXIuCgoqKkdlbmVyYWwgU3RhdGlzdGljcyBmcm9tIG11bHRpcWMqKgpgYGB7ciBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJywgd2FybmluZz1GQUxTRX0KbGlicmFyeShyZWFkcikKbGlicmFyeShmb3JtYXR0YWJsZSkKZGZfc3RhdHMgPC0gcmVhZF90c3YoIm11bHRpcWNfdHJpbV9mYXN0cS9nZW5lcmFsX3N0YXRzX3RhYmxlLnRzdiIsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpCmlzLm51bSA8LSBzYXBwbHkoZGZfc3RhdHMsIGlzLm51bWVyaWMpCmRmX3N0YXRzW2lzLm51bV0gPC0gbGFwcGx5KGRmX3N0YXRzW2lzLm51bV0sIHJvdW5kLCAxKQpmb3JtYXR0YWJsZShkZl9zdGF0cywgbGlzdCgKICAgICdQZXJjZW50RHVwcycgPSBjb2xvcl9iYXIoIiNFOTk2N0EiKSwKICAgICdQZXJjZW50R0MnID0gY29sb3JfYmFyKCIjREFBNTIwIiksCiAgICAnQlBNZWRpYW5SZWFkTGVuZ3RoJyA9IGNvbG9yX2JhcigiIzY2Q0RBQSIpLAogICAgJ01pbGxpb25zU2VxcycgPSBjb2xvcl9iYXIoIiNEQTcwRDYiKSksCiAgICB0YWJsZS5hdHRyID0gImNsYXNzPVwndGFibGUgdGFibGUtY29uZGVuc2VkXCcsIHN0eWxlPVwnd2lkdGg6ODAlOyBmb250LXNpemU6OTAlO1wnIgopCmBgYAoqKlNlcXVlbmNlIENvdW50cyBmb3IgZWFjaCBzYW1wbGUqKgoKIVtTZXF1ZW5jZSBDb3VudHNdKG11bHRpcWNfdHJpbV9mYXN0cS9tdWx0aXFjX3Bsb3RzL2Zhc3RxY19zZXF1ZW5jZV9jb3VudHNfcGxvdC5wbmcpe3dpZHRoPTU1MHB4fQoKKipUaGUgbWVhbiBxdWFsaXR5IHNjb3JlcyBwZXIgYmFzZSBpbiB0aGUgcmVhZCoqCgohW1BlciBCYXNlIFF1YWxpdHldKG11bHRpcWNfdHJpbV9mYXN0cS9tdWx0aXFjX3Bsb3RzL2Zhc3RxY19wZXJfYmFzZV9zZXF1ZW5jZV9xdWFsaXR5X3Bsb3QucG5nKXt3aWR0aD01NTBweH0KCioqVGhlIGF2ZXJhZ2UgcXVhbGl0eSBzY29yZXMgcGVyIHNlcXVlbmNlKioKCiFbUGVyIFNlcXVlbmNlIFF1YWxpdHldKG11bHRpcWNfdHJpbV9mYXN0cS9tdWx0aXFjX3Bsb3RzL2Zhc3RxY19wZXJfc2VxdWVuY2VfcXVhbGl0eV9zY29yZXNfcGxvdC5wbmcpe3dpZHRoPTU1MHB4fQoKKipUaGUgR0MgY29udGVudCBwZXIgc2VxdWVuY2UqKgoKIVtHQyBjb25ldGVudF0obXVsdGlxY190cmltX2Zhc3RxL211bHRpcWNfcGxvdHMvZmFzdHFjX3Blcl9zZXF1ZW5jZV9nY19jb250ZW50X3Bsb3QucG5nKXt3aWR0aD01NTBweH0KCgoqKlNlcXVlbmNlIER1cGxpY2F0aW9uKioKCiFbRHVwbGljYXRpb24gaW4gZWFjaCBzZXF1ZW5jZV0obXVsdGlxY190cmltX2Zhc3RxL211bHRpcWNfcGxvdHMvZmFzdHFjX3NlcXVlbmNlX2R1cGxpY2F0aW9uX2xldmVsc19wbG90LnBuZyl7d2lkdGg9NTUwcHh9CgoqKk92ZXJyZXByZXNlbnRlZCBzZXF1ZW5jZXMqKgoKIVtUb3RhbCBvdmVycmVwcmVzZW50ZWQgc2VxdWVuY2VzIGZvdW5kIGluIGVhY2ggc2FtcGxlXShtdWx0aXFjX3RyaW1fZmFzdHEvbXVsdGlxY19wbG90cy9mYXN0cWNfb3ZlcnJlcHJlc2VudGVkX3NlcXVlbmNlc19wbG90LnBuZyl7d2lkdGg9NTUwcHh9CgoqKk92ZXJhbGwgUGFzcy9GYWlsKioKCiFbQ2hlY2tpbmcgaWYgZWFjaCBzYW1wbGUgcGFzc2VzIG9yIGZhaWxzIGluIHZhcmlvdXMgbWV0ZXJpc10obXVsdGlxY190cmltX2Zhc3RxL211bHRpcWNfcGxvdHMvZmFzdHFjLXN0YXR1cy1jaGVjay1oZWF0bWFwLnBuZyl7d2lkdGg9NTUwcHh9CgoqKlNlcXVlbmNlIGxlbmd0aCBkaXN0cmlidXRpb24qKgoKIVtsZW5ndGggZGlzdHJpYnV0aW9uIG9mIHNlcXVlbmNlc10obXVsdGlxY190cmltX2Zhc3RxL211bHRpcWNfcGxvdHMvZmFzdHFjX3NlcXVlbmNlX2xlbmd0aF9kaXN0cmlidXRpb25fcGxvdC5wbmcpe3dpZHRoPTU1MHB4fQoKIyMgQWxpZ25tZW50CgpGaXJzdCB0aGluZ3MgZmlyc3QtIGNyZWF0ZSBhIGNvbmRhIGVudmlyb25tZW50IHRoYXQgaGFzIGJvd3RpZSwgc2FtdG9vbHMsIHBpY2FyZCwgYW5kIGJlZHRvb2xzLgoKYGNvbmRhIGNyZWF0ZSAtbiBjb25kYWJvd3RpZSBib3d0aWUgc2FtdG9vbHMgcGljYXJkIGJlZHRvb2xzYAoKVGhlIHRyaW1tZWQgcmVhZHMgYXJlIGFsaWduZWQgdG8gdGhlIHJlZmVyZW5jZSBnZW5vbWUgdXNpbmcgYm93dGllLgpUbyBhbmFseXplIHJlYWRzIG1hcHBpbmcgd2l0aCBtaXRvY2hvbmRyaWFsIGdlbm9tZSwgd2UgcGVyZm9ybSB0aGUgYWxpZ25tZW50IGluIHR3byBzdGVwcy4KCjEuIENvbXBsZXRlIEdlbm9tZSAod2l0aCBtaXRvY2hvbmRyaWFsIGdlbm9tZSktIHdpdGggYWxnZW5vbWUuZmEKMi4gT25seSB0aGUgTWl0b2Nob25kcmlhbCBnZW5vbWUgd2hpY2ggaXMgZXh0cmFjdGVkIGZyb20gZ2Vub21lLmZhLSBhbG1pdG9nZW5vbWUuZmEKClRvIGJlZ2luIGFsaWdubWVudCwgd2UgbWFrZSBib3d0aWUgaW5kZXhlcywgdGhpcyBpcyBkb25lIGluIHR3byBzZXRzLgoKYGBgCmJvd3RpZS1pbmRleCBhbGdlbm9tZS5mYQpib3d0aWUtaW5kZXggYWxtaXRvZ2Vub21lLmZhCmBgYAoKIyMjIEFsaWdubWVudCB3aXRoIGdlbm9tZQoKVGhlIGFsaWdubWVudCB3YXMgZG9uZSBvbiB0aGUgdHJpbW1lZCByZWFkcyBmcm9tIHByZXZpb3VzIHNlY3Rpb24uCgpgYGAKIyEvYmluL2Jhc2gKRklMRVM9Ii9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL3RyaW0vKi5mYXN0cSIKZm9yIGYgaW4gJEZJTEVTCiAgICBkbwogICAgICAgIGI9YGJhc2VuYW1lICRmYAogICAgICAgIGVjaG8gUnVubmluZyB0cmltbWluZyBmb3IgdGhlIGZpbGUgJGIKICAgICAgICB0PSR7Yjo6LTZ9CiAgICAgICAgbz0iJHQuc2FtIgogICAgICAgIHVvPSIkdC5tYXBwZWQuZnEiCiAgICAgICAgZWNobyBPdXRwdXQgZmlsZSBpcyAkbwogICAgICAgIGJvd3RpZSBcCgkgLXAgMjAgXAogICAgIAkgLXQgXAoJIC1rIDUgXAoJIC0tYmVzdCBcCgkgLS1zdHJhdGEgXAoJIC1lIDk5OTk5IFwKCSAtdiAwIFwKICAgCSAtbCAxNSBcCiAgCSAtLWNodW5rbWJzIDIwNDggXAoJIC14IC9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL2Jvd3RpZV9pbmRleF9hbGltL2FsZ2Vub21lIFwKCSAtcSAkZiBcCgkgLS1hbCAkdW8gXAoJIC0tc2FtIC0tbm8tdW5hbCA+ICRvIDI+ICR0LmJvd3RpZS5sb2cKICAgIGRvbmUKI2RvbmUKYGBgCgpUaGUgZm9sbG93aW5nIHN0YXRzIHNob3cgYWxpZ25tZW50IFFDLiAKCiFbQm93dGllIEFsaWdubWVudCBTdGF0cyB3aXRoIEdlbm9tZV0oYWxpZ25tZW50L2dlbm9tZS9ib3d0aWUxX2FsaWdubWVudC5wbmcpe3dpZHRoPTU1MHB4fQoKVGhpcyB0YWJsZSBzaG93cyB0aGUgbnVtYmVyIG9mIHJlYWRzIGFsaWduZWQgaW4gZWFjaCBzYW1wbGUgKE1pbGxpb25BbGlnbmVkUmVhZHMpLiAKSXQgYWxzbyBzaG93cyB0aGUgbnVtYmVyIG9mIGFsaWdtZW50cyBvZiB2YXJpb3VzIHJlYWRzIHRoYXQgaW5jbHVkZXMgbXVsdGltYXBwZWQgcmVhZHMgKE1pbGxpb25NYXBwZWRSZWFkcykuCgpgYGB7ciBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJywgd2FybmluZz1GQUxTRX0KbGlicmFyeShyZWFkcikKbGlicmFyeShmb3JtYXR0YWJsZSkKZGZfc3RhdHMgPC0gcmVhZF90c3YoImFsaWdubWVudC9nZW5vbWUvZ2VuZXJhbF9zdGF0c190YWJsZS50c3YiLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKQppcy5udW0gPC0gc2FwcGx5KGRmX3N0YXRzLCBpcy5udW1lcmljKQpkZl9zdGF0c1tpcy5udW1dIDwtIGxhcHBseShkZl9zdGF0c1tpcy5udW1dLCByb3VuZCwgMSkKZm9ybWF0dGFibGUoZGZfc3RhdHMsIGxpc3QoCQogICAgJ1BlcmNlbnRBbGlnbmVkJyA9IGNvbG9yX2JhcigiI0IwQzRERSIpLAogICAgJ01pbGxpb25BbGlnbmVkUmVhZHMnID0gY29sb3JfYmFyKCIjRTZFNkZBIiksCiAgICAnTWlsbGlvbk1hcHBlZFJlYWRzJyA9IGNvbG9yX2JhcigiIzc3ODg5OSIpLAogICAgdGFibGUuYXR0ciA9ICJjbGFzcz1cJ3RhYmxlIHRhYmxlLWNvbmRlbnNlZFwnLCBzdHlsZT1cJ3dpZHRoOjgwJTsgZm9udC1zaXplOjkwJTtcJyIpCikKYGBgCiMjIyBBbGlnbm1lbnQgd2l0aCBtaXRvY2hvbmRyaWEKClRoZSBhbGlnbm1lbnQgd2FzIGRvbmUgb24gdGhlIHRyaW1tZWQgcmVhZHMgZnJvbSBwcmV2aW91cyBzZWN0aW9uLgoKVGhlIGZvbGxvd2luZyBzdGF0cyBzaG93IGFsaWdubWVudCBRQy4gCgpgYGAKIyEvYmluL2Jhc2gKRklMRVM9Ii9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL3RyaW0vKi5mYXN0cSIJCmZvciBmIGluICRGSUxFUwogICAgZG8KICAgICAgICBiPWBiYXNlbmFtZSAkZmAKICAgICAgICBlY2hvIFJ1bm5pbmcgYWxpZ25tZW50IGZvciB0aGUgZmlsZSAkYgogICAgICAgIHQ9JHtiOjotNn0KICAgICAgICBvPSIkdC5zYW0iCgl1bz0iJHQubWFwcGVkLmZxIgogICAgICAgIGVjaG8gT3V0cHV0IGZpbGUgaXMgJG8KICAgICAgICBib3d0aWUgXAoJIC1wIDIwIFwKICAgICAJIC10IFwKCSAtayAxMCBcCgkgLS1iZXN0IFwKCSAtLXN0cmF0YSBcCgkgLWUgOTk5OTkgXAoJIC12IDAgXAogICAJIC1sIDE1IFwKICAJIC0tY2h1bmttYnMgMjA0OCBcCgkgLXggL2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvYm93dGllX21pdG9faW5kZXgvYWxtaXRvZ2Vub21lIFwKCSAtcSAkZiBcCgkgLS1hbCAkdW8gXAoJIC0tc2FtIC0tbm8tdW5hbCA+ICRvIDI+ICR0LmJvd3RpZS5sb2cKICAgIGRvbmUKI2RvbmUKYGBgCgohW0Jvd3RpZSBBbGlnbm1lbnQgU3RhdHMgd2l0aCBNaXRvY2hvbmRyaWFsIEdlbm9tZV0oYWxpZ25tZW50L21pdG9jaG9uZHJpYS9ib3d0aWUxX2FsaWdubWVudC5wbmcpe3dpZHRoPTU1MHB4fQoKVGhpcyB0YWJsZSBzaG93cyB0aGUgbnVtYmVyIG9mIHJlYWRzIGFsaWduZWQgaW4gZWFjaCBzYW1wbGUgKE1pbGxpb25BbGlnbmVkUmVhZHMpLiAKSXQgYWxzbyBzaG93cyB0aGUgbnVtYmVyIG9mIGFsaWdtZW50cyBvZiB2YXJpb3VzIHJlYWRzIHRoYXQgaW5jbHVkZXMgbXVsdGltYXBwZWQgcmVhZHMgKE1pbGxpb25NYXBwZWRSZWFkcykuCgpgYGB7ciBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJywgd2FybmluZz1GQUxTRX0KbGlicmFyeShyZWFkcikKbGlicmFyeShmb3JtYXR0YWJsZSkKZGZfc3RhdHMgPC0gcmVhZF90c3YoImFsaWdubWVudC9taXRvY2hvbmRyaWEvZ2VuZXJhbF9zdGF0c190YWJsZS50c3YiLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKQppcy5udW0gPC0gc2FwcGx5KGRmX3N0YXRzLCBpcy5udW1lcmljKQpkZl9zdGF0c1tpcy5udW1dIDwtIGxhcHBseShkZl9zdGF0c1tpcy5udW1dLCByb3VuZCwgMikKZm9ybWF0dGFibGUoZGZfc3RhdHMsIGxpc3QoCQogICAgJ1BlcmNlbnRBbGlnbmVkJyA9IGNvbG9yX2JhcigiI0IwQzRERSIpLAogICAgJ01pbGxpb25BbGlnbmVkUmVhZHMnID0gY29sb3JfYmFyKCIjRTZFNkZBIiksCiAgICAnTWlsbGlvbk1hcHBlZFJlYWRzJyA9IGNvbG9yX2JhcigiIzc3ODg5OSIpLAogICAgdGFibGUuYXR0ciA9ICJjbGFzcz1cJ3RhYmxlIHRhYmxlLWNvbmRlbnNlZFwnLCBzdHlsZT1cJ3dpZHRoOjgwJTsgZm9udC1zaXplOjkwJTtcJyIpCikKYGBgCkFub3RoZXIgUUMgdGhhdCB3ZSBjb3VsZCBmbyB3aXRoIHRoZSBhbGlnbmVkIHJlYWQgaXMgd2l0aCBQaWNhcmQuIFRoZSBmb2xsb3dpbmcgaXMgdGhlIGNvbW1hbmQgbGluZSB0byBkbyB0aGF0OgoKYGBgCkZJTEVTPSIvZGlzay9iaW9zY3JhdGNoL1BvZHJhYl9sYWIvZ2F6YWwvc1JOQV9nYXphbC9hbGlnbl93aXRoX2FsaW1fZm9yX2Fubm8vYWxpbV9taXRvX2Fubm8vKnNvcnRlZC5iYW0iCmZvciBmIGluICRGSUxFUwogICAgZG8KICAgICAgICBiPWBiYXNlbmFtZSAkZmAKICAgICAgICBlY2hvIENvbnZlcnRpbmcgZmlsZSAkYgogICAgICAgIG89IiRiLnBpY2FyZC50eHQiCiAgICAgICAgZWNobyBPdXRwdXQgZmlsZSBpcyAkbwoJcGljYXJkIC1YbXg1ZyBDb2xsZWN0QWxpZ25tZW50U3VtbWFyeU1ldHJpY3MgST0kZiBPPSRvIFI9L2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvY29waWVkX29sZF9pbmZpbGVzL0dDRl8wMDEyNjY3NzUuMV9BdXN0cm9mdW5kdWx1c19saW1uYWV1cy0xLjBfZ2Vub21pY19hbmRNSVRPLmZuYQogICAgZG9uZQojZG9uZQoKYGBgCgpCZWZvcmUgd2UgcHJvY2VlZCwgd2UgbmVlZCB0byBzb3J0IHRoZSBzYW0sIGNvbnZlcnQgaXQgaW50byBiYW0gYW5kIGNyZWF0ZSBhIGJhbSBpbmRleCAoYmFpKS4KVGhpcyBzdGVwIGVuc3VyZXMgdGhhdCB3ZSBjb3VsZCBzdG9yZSB0aGUgYWxpZ25tZW50cyBpbiBhY2NlcHRhYmxlIGJpbmFyeSBmb3JtYXQgdGhhdCB0YWtlcyBsZXNzIHN0b3JhZ2Ugc3BhY2UKYW5kIGlzIGNvbXBhdGlibGUgd2l0aCBzdWJzZXF1ZW50IHN0ZXBzLgoKCmBgYApGSUxFUz0iL2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvYWxpZ25fd2l0aF9hbGltX2Zvcl9hbm5vL2FsaW1fbWl0b19hbm5vLyouc2FtIgpmb3IgZiBpbiAkRklMRVMKICAgIGRvCiAgICAgICAgYj1gYmFzZW5hbWUgJGZgCiAgICAgICAgZWNobyBDb252ZXJ0aW5nICRiIHRvIGJhbQogICAgICAgIG89JHtiOjotNH0KICAgICAgICBiYW09IiRvLmJhbSIKCXNvcnRlZGJhbT0iJGIuc29ydGVkLmJhbSIKCQoJZWNobyBUbXAgZmlsZSBpcyAkYmFtCiAgICAgICAgc2FtdG9vbHMgdmlldyAtYiAkZiA+ICRiYW0KCQogICAgICAgIGVjaG8gT3V0cHV0IGZpbGVzIGFyZSAkc29ydGVkYmFtIGFuZCBpdHMgaW5kZXgKCXNhbXRvb2xzIHNvcnQgJGJhbSAtbyAkc29ydGVkYmFtCglzYW10b29scyBpbmRleCAkc29ydGVkYmFtCgllY2hvIERlbGV0aW5nIFRtcCBmaWxlICRiYW0gCglybSAkYmFtIAogICAgZG9uZQojZG9uZQpgYGAKCiMjIFVzaW5nIGFsaWduZWQgcmVhZHMKCldlIHdpbGwgY3JlYXRlIHRocmVlIGZpbGVzOgoKMS4gU3VtbWFyeSBpbmZvcm1hdGlvbiB0aGF0IGhhcyByZWFkIElELCBzZXF1ZW5jZSwgcmVmZXJlbmNlIGxvY2F0aW9uLCBhbmQgbnVtYmVyIG9mIGFsaWdubWVudHMuCjIuIEV4YWN0IGxvY2F0aW9uLCBnZW5vbWljIGZlYXR1cmVzIG9mIHRoZSByZWZlcmVuY2UgbG9jYXRpb24gdGhhdCB0aGUgcmVhZHMgbWFwcGVkIHRvIHZpYSBiZWR0b29scy4KMy4gQ291bnRpbmcgdGhlIHJlYWRjb3VudHMgZnJvbSBiYW0gZmlsZXMuCgpgYGAjIS9iaW4vYmFzaApGSUxFUz0iL2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvYWxpZ25fd2l0aF9hbGltX2Zvcl9hbm5vL2FsaW1fbWl0b19hbm5vLyouYmFtIgpmb3IgZiBpbiAkRklMRVMKICAgIGRvCiAgICAgICAgYj1gYmFzZW5hbWUgJGZgCiAgICAgICAgZWNobyAkYgogICAgICAgIG89JHtiOjotNH0KICAgICAgICBvPSIkby5zdW1tYXJ5LnR4dCIKCWlucHV0X2ZpbGU9IiRmIgoJb3V0cHV0X2ZpbGU9IiRvLnN1bW1hcnkudHh0IgoKCSMgUHJvY2VzcyB0aGUgaW5wdXQgZmlsZSB3aXRoIHNhbXRvb2xzIGFuZCBhd2sKCXNhbXRvb2xzIHZpZXcgJGYgfCBhd2sgJ3twcmludCAkMSwgJDEwLCAkMywgJDQsICQxNX0nIHwgc29ydCB8IHVuaXEgPiAiJG91dHB1dF9maWxlIgoJZWNobyAiT3V0cHV0IGZpbGUgd3JpdHRlbiAkb3V0cHV0X2ZpbGUiCiAgICBkb25lCmBgYApUaGUgcmVzdWx0IGlzIHRoZSBmb2xsb3dpbmcgZGF0YSBmb3IgZWFjaCBmaWxlLiBUaGUgc2FtcGxlIDFfMTJkX3QwIGlzIHNob3duLgohW10oc2NyZWVucy9zdW1tYXJ5XzFfMTJkX3QwLnBuZykKCmBgYCMhL2Jpbi9iYXNoCkZJTEVTPSIvZGlzay9iaW9zY3JhdGNoL1BvZHJhYl9sYWIvZ2F6YWwvc1JOQV9nYXphbC9hbGlnbl93aXRoX2FsaW1fZm9yX2Fubm8vYWxpbV9taXRvX2Fubm8vKi5iYW0iCmZvciBmIGluICRGSUxFUwogICAgZG8KICAgICAgICBiPWBiYXNlbmFtZSAkZmAKICAgICAgICBlY2hvICRiCiAgICAgICAgbz0ke2I6Oi00fQogICAgICAgIGJlZD0iJG8uYmVkIgoJb3V0PSIkby5iZWR0b29scy50eHQiCglnZmY9Ii9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL21pdG9fZ2Vub21lL0dDRl8wMDEyNjY3NzUuMV9BdXN0cm9mdW5kdWx1c19saW1uYWV1c19NSVRPb25seS5nZmYiCgliZWR0b29scyBpbnRlcnNlY3QgLWEgJGYgLWIgJGdmZiAtd28gLWYgMSAtYmVkID4gJGJlZAoJYXdrICchc2VlblskNF0rKycgJGJlZCA+IHRtcC5jc3YKCXJtICRiZWQKCWF3ayAne3ByaW50ICQ0LCAkMjF9JyB0bXAuY3N2ID4gJG91dAoJcm0gdG1wLmNzdgoJZWNobyAiT3V0cHV0IGZpbGUgd3JpdHRlbiAkb3V0IgogICAgZG9uZQoKYGBgClRoZSByZXN1bHQgb2YgYWJvdmUgY29tbWFuZCBnaXZlcyB1cyB0aGUgZm9sbG93aW5nIGRhdGEgZm9yIGVhY2ggZmlsZS4gVGhlIHNhbXBsZSAxXzEyZF90MCBpcyBzaG93bi4KIVtdKHNjcmVlbnMvYmVkdG9vbHNfMV8xMmRfdDAucG5nKQoKCmBgYCMhL2Jpbi9iYXNoCkZJTEVTPSIvZGlzay9iaW9zY3JhdGNoL1BvZHJhYl9sYWIvZ2F6YWwvc1JOQV9nYXphbC9hbGlnbl93aXRoX2FsaW1fZm9yX2Fubm8vYWxpbV9taXRvX2Fubm8vKi5iYW0iCmZvciBmIGluICRGSUxFUwogICAgZG8KICAgICAgICBiPWBiYXNlbmFtZSAkZmAKICAgICAgICBlY2hvICRiCiAgICAgICAgbz0ke2I6Oi00fQogICAgICAgIG89IiRvLnJlYWRjb3VudC50eHQiCiAgICAgICAgZWNobyBPdXRwdXQgZmlsZSBpcyAkbwoJIyBDb3VudCB1bmlxdWUgb2NjdXJyZW5jZXMgb2YgY29sdW1uIDEwCglzYW10b29scyB2aWV3ICRmIHwgYXdrICd7cHJpbnQgJDEwfSd8IHNvcnQgfCB1bmlxIC1jID4gIiRvIgoJZWNobyAiT3V0cHV0IHdyaXR0ZW4gdG8gJG8iCiAgICBkb25lCgpgYGAKVGhlIHJlc3VsdCBvZiBhYm92ZSBjb21tYW5kIGdpdmVzIHVzIHRoZSBmb2xsb3dpbmcgZGF0YSBmb3IgZWFjaCBmaWxlLiBUaGUgc2FtcGxlIDFfMTJkX3QwIGlzIHNob3duLgohW10oc2NyZWVucy9yZWFkY291bnRfMV8xMmRfdDAucG5nKQoKIyMjIG1pUlRyYWNlCiBSdW5uaW5nIG1pcnRyYWNlIHdpdGggdGhlIGZvbGxvd2luZyBjb21tYW5kLgoKYGBgIyEvYmluL2Jhc2gKbWlydHJhY2UgcWMgLS1zcGVjaWVzIGRyZSAtLWNvbmZpZyBzZXFfYWRkcmVzcy50eHQKYGBgCgpMb29raW5nIGF0IHRoZSByZXN1bHRzOgoKIVtdKG1pcnRyYWNlL21pcnRyYWNlLWxlbmd0aC1wbG90LnBuZyl7d2lkdGg9MTAwJX0KIVtdKG1pcnRyYWNlL21pcnRyYWNlLXJuYXR5cGUtcGxvdC5wbmcpe3dpZHRoPTEwMCV9CgojIyMgc3BvcnRzCgpFeGVjdXRpbmcgc3BvcnRzIHRvb2wgb24gbWFwcGVkIHJlYWRzIG9ubHkuIFdlIHVzZSB0aGUgZm9sbG93aW5nIGNvbW1hbmQgdG8gcnVuOgoKYGBgCiMhL2Jpbi9iYXNoCnNwb3J0cy5wbCAtaSBzZXFzX2FsaW1fbWl0by50eHQgXAotbyAvZGlzay9iaW9zY3JhdGNoL1BvZHJhYl9sYWIvZ2F6YWwvc1JOQV9nYXphbC9hbGlnbl93aXRoX2FsaW1uYWV1cy9nZW5faW5wdXRfZmFzdHEvU1BPUlRTL291dF9zcG9ydHMvUkVETy9taXRvX21hcHBlZF9yZWFkcyBcCi1rIFwKLU0gMiBcCi1wIDIwIFwKLWcgL2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvYm93dGllX21pdG9faW5kZXgvYWxtaXRvZ2Vub21lIFwKLW0gL2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvYWxpZ25fd2l0aF9hbGltbmFldXMvZ2VuX2lucHV0X2Zhc3RxL1NQT1JUUy9zcG9ydHMxLjEvZGIvRGFuaW9fcmVyaW8vbWlSQmFzZV8yMS9taVJCYXNlXzIxLWRyZSBcCi1yIC9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL2FsaWduX3dpdGhfYWxpbW5hZXVzL2dlbl9pbnB1dF9mYXN0cS9TUE9SVFMvc3BvcnRzMS4xL2RiL0RhbmlvX3JlcmlvL3JSTkFfZGIvemVicmFmaXNoX3JSTkEgXAotdCAvZGlzay9iaW9zY3JhdGNoL1BvZHJhYl9sYWIvZ2F6YWwvc1JOQV9nYXphbC9hbGlnbl93aXRoX2FsaW1uYWV1cy9nZW5faW5wdXRfZmFzdHEvU1BPUlRTL3Nwb3J0czEuMS9kYi9EYW5pb19yZXJpby9HdFJOQWRiL2RhblJlcjYtdFJOQXMgXAotdyAvZGlzay9iaW9zY3JhdGNoL1BvZHJhYl9sYWIvZ2F6YWwvc1JOQV9nYXphbC9hbGlnbl93aXRoX2FsaW1uYWV1cy9nZW5faW5wdXRfZmFzdHEvU1BPUlRTL3Nwb3J0czEuMS9kYi9EYW5pb19yZXJpby9waVJCYXNlL3BpUl9kcmVfdjEuMCBcCi1lIC9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL2FsaWduX3dpdGhfYWxpbW5hZXVzL2dlbl9pbnB1dF9mYXN0cS9TUE9SVFMvc3BvcnRzMS4xL2RiL0RhbmlvX3JlcmlvL0Vuc2VtYmwvRGFuaW9fcmVyaW8uR1JDejEwLm5jcm5hIFwKLWYgL2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvYWxpZ25fd2l0aF9hbGltbmFldXMvZ2VuX2lucHV0X2Zhc3RxL1NQT1JUUy9zcG9ydHMxLjEvZGIvRGFuaW9fcmVyaW8vUmZhbV8xMi4zL1JmYW0tMTIuMy16ZWJyYWZpc2gKYGBgCgpUaGlzIHdpbGwgZ2VuZXJhdGUgYSBudW1iZXIgb2Ygb3V0cHV0IGZpbGVzLCBmcm9tIHdoaWNoIHRoZSB0YWJsZXMKZ2VuZXJhdGVkIGFzIGEgcmVzdWx0IGZpbGUgKl9vdXRwdXQudHh0IGZvciBlYWNoIHNhbXBsZSBhcmUgdGFrZW4gYW5kIAphcmUgdXNlZCB0byBleHRyYWN0IGFubm90YXRpb24gb2YgbWFwcGVkIHJlYWRzLgpUb3AgNTAgcm93cyBvZiB0aGlzIHRhYmxlIGFyZSBzaG93biBmb3IgdGhlIHNhbXBsZSAxMF8xMmRfNGhyQSBiZWxvdy4gCgoKIVtdKHNwb3J0cy9TY3JlZW5zaG90ZnJvbTEwXzEyZF80aHJBLnBuZyl7d2lkdGg9NTUwcHh9CgpJdCBhbHNvIGdlbmVyYXRlcyBhIG51bWJlciBvZiBwbG90cyB0byBjYXRlZ29yaXplIHRoZSBhbm5vdGF0aW9ucyAKYW5kIHRoZWlyIGxlbmd0aCBkaXN0cmlidXRpb25zIGZvciBlYWNoIHNhbXBsZS4KCiFbXShzcG9ydHMvU2NyZWVuc2hvdDEwXzEyZF80aHJBLnBuZyl7d2lkdGg9NTUwcHh9CiFbXShzcG9ydHMvU2NyZWVuc2hvdDEwXzEyZF80aHJBX2dyYXBoLnBuZyl7d2lkdGg9NTUwcHh9CgojIyBDb21waWxpbmcgb3V0cHV0IGZpbGVzCgpBdCB0aGUgZW5kLCB3ZSBuZWVkIHRvIGNvbXBpbGUgYWxsIHRoZSBvdXRwdXQgZmlsZXMgaW50byBhIHNpbmdsZSBkYXRhZnJhbWUgdGhhdCBjYW4gYmUgZXhwb3J0ZWQKdG8gZnVydGhlciBkbyBkb3duc3RyZWFtIHByb2Nlc3Npbmcgc3VjaCBhcyBzdGF0aXN0aWNzLCBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiwgYW5kIGNsdXN0ZXJpbmcuCgpXZSBwcm92aWRlIGFuIFtSIHNjcmlwdF0oc2NyaXB0cy9tZXJnZV9jb3VudHNfbWl0by5SKSB0aGF0IGNvbXBpbGVzIHRoZXNlIG91dHB1dCBmaWxlczoKCjEuIEFubm90YXRpb246IEZyb20gKipzcG9ydHMqKi0gKi5tYXBwZWRfb3V0cHV0LnR4dAoyLiBBbGlnbm1lbnQgc3VtbWFyeTogRnJvbSAuYmFtIGZpbGVzIHdpdGggKipzYW10b29scyoqLSAqLnN1bW1hcnkudHh0CjMuIFJlYWRjb3VudDogRnJvbSAuYmFtIGZpbGVzIHdpdGggKipzYW10b29scyoqIGFuZCAqKmF3ayoqLSAqLnJlYWRjb3VudC50eHQKNC4gTG9jYXRpb246IEZyb20gLmJhbSBmaWxlcyB3aXRoICoqYmVkdG9vbHMqKi0gKi5iZWR0b29scy50eHQKCkluIGFkZGl0aW9uLCB3ZSBhbHNvIG5lZWQgYSBzYW1wbGUgZGVzaWduIGZpbGUgKC5jc3YgZm9ybWF0KSB0aGF0IGhhcyBkZXRhaWxzIGFib3V0IHRoZSBzYW1wbGVzLgpUaGlzIGZpbGUgbWFrZXMgaXQgZWFzaWVyIHRvIGRvIHN0YXRpc3RpY2FsIGFuYWx5c2lzIG9uIHRoZSBkYXRhIHVzaW5nIFIgcGFja2FnZXMgbGlrZSAKREVTZXEyLCBFeHByZXNzaW9uU2V0LCBhbmQgRWRnZVIuCgpZb3Ugd291bGQgYWx0ZXIgdGhlIGZvbGxvd2luZyBsaW5lcyBpbiB0aGUgUiBzY3JpcHQgdGhhdCBiYXNpY2FsbHkgdGVsbHMgdGhlIHByb2dyYW0gd2hlcmUgdGhlc2UgdHh0IGZpbGVzIGFyZSBsb2NhdGVkLgoKYGBge3IsIGV2YWw9RkFMU0V9CnBhcmVudF9kaXIgPC0gIkQ6L1BTVV93b3JrL3Ntcm5hc2VxL21pdG9fbWFwIgpzYW1wbGVzIDwtICJEOi9QU1Vfd29yay9zbXJuYXNlcS9taXRvX21hcC9kZXNpZ25fc2FtcGxlcy5jc3YiCnJlYWRjb3VudF90eHRfcGF0dGVybiA8LSAic29ydGVkLnJlYWRjb3VudC50eHQkIgpvdXRwdXRfdHh0X3BhdHRlcm4gPC0gIm1hcHBlZF9vdXRwdXQudHh0JCIKc3VtbWFyeV90eHRfcGF0dGVybiA8LSAic3VtbWFyeS50eHQkIgpiZWR0b29sc190eHRfcGF0dGVybiA8LSAiYmVkdG9vbHMudHh0JCIKYGBgCgpTZXQgcGF0dGVybiBvZiBmaWxlbmFtZXM6IHRoZXNlIGZpbGVzIGFyZSBzZWFyY2hlZCBpbiB0aGUgcGFyZW50X2RpciByZWN1cnNpdmVseS4KTWFrZSBzdXJlIHRoYXQgdGhlIHBhcmVudF9kaXIgY29udGFpbnMgdGhlc2UgZmlsZXMgYW5kIHRoZSBwYXR0ZXJuIHNob3VsZCBiZSB1bmlxdWUgdG8gbGlzdCB0aGUgZmlsZXMgdGhhdCB3ZSBuZWVkLgoKIyMgVmlzdWFsaXppbmcKV2UgdXNlIHRoZSBhbGlnbm1lbnRzIHdpdGggbWl0b2Nob25kcmlhbCBnZW5vbWUgdG8gdmlldyB0aGUgYWxpZ25lZCByZWFkcy4KCkpicm93c2UgaXMgdXNlZCB0byBleHBsb3JlIGFsaWdubWVudHMuCgpGaWxlcyB1c2VkOgoKMS4gQWxpZ25lZCBiYW0gZmlsZXMgZm9yIGVhY2ggc2FtcGxlIGFuZCBpdHMgY29ycmVzcG9uZGluZyBpbmRleCBmaWxlIChiYW0sIGJhaSkKMy4gUmVmZXJlbmNlIGdlbm9tZSBmb3IgbWl0b2Nob25kcmlhICguZmFzdGEpIGFuZCBpdHMgaW5kZXggZmlsZSAoLmZhaSkKNC4gR2Vub21lIGZlYXR1cmUgZmlsZSAoLmdmZikgZm9yIG1pdG9jaG9uZHJpYWwgZ2Vub21lCgohW10oamJyb3dzZS9qYnJvd3NlXzRkX3QwLnN2ZykKPGEgaHJlZj0iamJyb3dzZS9qYnJvd3NlXzRkX3QwLnN2ZyIgdGFyZ2V0PSJfYmxhbmsiPiBDbGljayB0byBlbmxhcmdlPC9hPgoKVGhpcyBmaWd1cmUgc2hvd3MgbWl0b2Nob25kaXJhbCBnZW5vbWUgb2YgMTAwYnAgbGVuZ3RoIGZyb20gMTcxMDAgdG8gMTcxOTkuIE9uIHRoaXMgZ2Vub21lLCB3ZSBzZWUgCjEpIHRoZSBjb2xvcmVkIGJhc2VwYWlycywgMikgR2Vub21pYyBmZWF0dXJlcyBvZiB0aGUgbWVudGlvbmVkIGxlbmd0aCwgMykgQWxpZ25tZW50cyBmcm9tIDQgc2FtcGxlcyAoNGQgdDAgcmVwbGljYXRlcykKdGhhdCBzaG93IHJlYWRzIGFsaWduZWQgdG8gdGhlIGdlbm9tZSBjb2xvcmVkIGJ5IHN0cmFuZCB3aGlsZSBhbHNvIHNob3dpbmcgdGhlIGNvdmVyYWdlIGhpc3RvZ3JhbSBpbiBncmV5LiA=